package com.computergames.server.server.handler;

import com.computergames.server.domain.ClientState;
import com.computergames.server.message.ReconnectRequestMessage;
import com.computergames.server.message.ReconnectResponseMessage;
import com.computergames.server.server.session.SessionFactory;
import com.computergames.server.service.Implement.GobangMessageHandlerFactory;
import com.computergames.server.service.Implement.GobangStorage;
import com.computergames.server.service.Interface.CheckAndUpdateClientState;
import com.computergames.server.service.Interface.GameMessageHandlerFactory;
import com.computergames.server.service.reconnect.ReconnectStrategySelector;
import com.computergames.server.util.RedisUtil;
import com.computergames.server.util.SpringUtil;
import io.netty.channel.*;

import io.netty.util.AttributeKey;

import java.util.List;

@ChannelHandler.Sharable
public class ReconnectRequestMessageHandler extends SimpleChannelInboundHandler<ReconnectRequestMessage> {
    CreateRoomRequestMessageHandler CREATE_ROOM_HANDLER = new CreateRoomRequestMessageHandler();
    JoinRoomRequestMessageHandler JOIN_ROOM_HANDLER = new JoinRoomRequestMessageHandler();
    QuitRoomRequestMessageHandler QUIT_ROOM_HANDLER = new QuitRoomRequestMessageHandler();
    MoveRequestMessageHandler MOVE_HANDLER = new MoveRequestMessageHandler();
    ReadyRequestMessageHandler READY_HANDLER = new ReadyRequestMessageHandler();
    AcknowledgeMessageHandler ACKNOWLEDGE_HANDLER = new AcknowledgeMessageHandler();
    BidRequestMessageHandler BID_HANDLER = new BidRequestMessageHandler();
    QuitHandler QUIT_HANDLER = new QuitHandler();

    private static final AttributeKey<String> USER_IDENTIFIER_KEY = AttributeKey.valueOf("USER_IDENTIFIER");
    private static final AttributeKey<String> USER_STAGE_KEY = AttributeKey.valueOf("USER_STAGE");
    private static final AttributeKey<String> USER_ROOM_KEY = AttributeKey.valueOf("USER_ROOM");
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ReconnectRequestMessage msg) throws Exception {
        ChannelPipeline pipeline = ctx.pipeline();
        pipeline.addLast(CREATE_ROOM_HANDLER);
        pipeline.addLast(JOIN_ROOM_HANDLER);
        pipeline.addLast(READY_HANDLER);
        pipeline.addLast(ACKNOWLEDGE_HANDLER);
        pipeline.addLast(BID_HANDLER);
        pipeline.addLast(QUIT_ROOM_HANDLER);
        pipeline.addLast(MOVE_HANDLER);
        pipeline.addLast(QUIT_HANDLER);

        CheckAndUpdateClientState checkAndUpdateClientState = SpringUtil.getBean(CheckAndUpdateClientState.class);
        // 获取断线前通道
        Channel oldChannel = SessionFactory.getSession().getChannel(msg.getUsername());
        // 获取断线前通道状态
        ClientState State = checkAndUpdateClientState.getState(oldChannel);
        // 重新设置用户标识
        ctx.channel().attr(USER_IDENTIFIER_KEY).set(msg.getUsername());
        // 重新设置用户比赛阶段
        ctx.channel().attr(USER_STAGE_KEY).set(oldChannel.attr(USER_STAGE_KEY).get());
        // 重新设置用户房间
        if(oldChannel.attr(USER_ROOM_KEY).get() != null){
            ctx.channel().attr(USER_ROOM_KEY).set(oldChannel.attr(USER_ROOM_KEY).get());
        }

        SessionFactory.getSession().unbind(oldChannel);
        checkAndUpdateClientState.removeState(oldChannel);

        SessionFactory.getSession().bind(ctx.channel(),msg.getUsername());
        checkAndUpdateClientState.updateState(ctx.channel(), State);

        if(checkAndUpdateClientState.checkState(ctx, ClientState.GAME_STARTED)){
            ReconnectStrategySelector selector = SpringUtil.getBean(ReconnectStrategySelector.class);
            RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
            String roomType = redisUtil.hget(ctx.channel().attr(USER_ROOM_KEY).get(), "roomType").toString();

            selector.select(ctx,roomType);
        }
    }
}
